package app.Insam.VNC;

import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;

public class InsamLocationManager implements LocationListener {
	public static final String TAG = "InsamLocationManager";
	
	protected InsamService mParent;
	protected InsamScheduler mScheduler;
	
	protected LocationManager mLocationManager;
	protected String mProvider;
	protected InsamLocationInfo mCurLocation;	
	
	public InsamLocationManager(InsamService _Parent, InsamScheduler _scheduler) {
		mParent = _Parent;
		mScheduler = _scheduler;
		mCurLocation = new InsamLocationInfo(0,0);
		mLocationManager = (LocationManager)mParent.getSystemService(Context.LOCATION_SERVICE);	
		mProvider = mLocationManager.getBestProvider(new Criteria(), true);
//		mProvider = LocationManager.NETWORK_PROVIDER;
	}
	
	protected void checkLocation(String _provider) {
		if(InsamApp.OfficeLocation==null) {
			mParent.stopSelf();
			return;
		}
		
		Log.v(TAG, "requestLocationUpdate(with " + _provider + ")");
		mLocationManager.requestLocationUpdates(_provider, InsamApp.TIME_RESCAN_MINIMUM, 0, this);			
	}
	
	protected void checkLocation() {
		checkLocation(mProvider);
	}
	
	public void stop() {
		Log.d(TAG, "stop LocationManager");
		mLocationManager.removeUpdates(this);
	}

	public void onLocationChanged(Location _location) {
		Log.d(TAG, "Location Updated");
		
		mLocationManager.removeUpdates(this);
		double oldDis = CalcDistanceFromOffice(mCurLocation);
		mCurLocation.SetLocation(_location);
		double curDis = CalcDistanceFromOffice(mCurLocation);			
		Log.d(TAG, String.format("%s, dis:%fm", mCurLocation, curDis));
		
		float accu = _location.getAccuracy();
		if(curDis < _location.getAccuracy()) {
			InsamDebugger.notify(String.format("Near Office. %.2fm(accu:%.2fm)", curDis, accu));
			mScheduler.execute(InsamService.ACTION_SCAN_WIFI);
			return;
		}
		
		int delay = (int)(curDis * InsamApp.MILISEC_PER_METER);
				
		if(delay < InsamApp.TIME_RESCAN_MINIMUM) {	//delay correction
			delay=InsamApp.TIME_RESCAN_MINIMUM;
		} 
		
		if(accu < 500) {			//accuracy correction
			accu = 500;
		}
		
		if(curDis-oldDis>accu) {	//far away from Office
			delay<<=1;
		}
			
		InsamDebugger.notify(String.format("dis:%.2fm(%.1fm), update %ds", curDis, _location.getAccuracy(), delay/1000));
		mScheduler.schedule(InsamService.ACTION_SCAN_LOCATION, delay);
	}
	
	public double CalcDistanceFromOffice(InsamLocationInfo _location) {		     
        return _location.CalcDistance(InsamApp.OfficeLocation);
	}
	

	public void onProviderDisabled(String _provider) {
		// TODO Auto-generated method stub
	}


	public void onProviderEnabled(String _provider) {
		// TODO Auto-generated method stub
	}

	public void onStatusChanged(String _arg0, int _arg1, Bundle _arg2) {
		// TODO Auto-generated method stub
	}
}
